﻿using System;
using System.Collections.Generic;
using System.Text;

namespace MYTech.Oracle
{
    /// <summary>
    /// 表字段
    /// </summary>
    public class Field
    {
        /// <summary>
        /// 构造表字段实例
        /// </summary>
        public Field()
        { }

        /// <summary>
        /// 构造表字段实例
        /// </summary>
        /// <param name="expression"></param>
        public Field(string expression)
        {
            if (!string.IsNullOrEmpty(expression))
            {
                string _exp = expression.ToUpper().Trim();
                int posNull = _exp.IndexOf("NOT NULL");
                if (posNull > 0)
                {
                    _NullAble = false;
                }
                int posDef = _exp.IndexOf("DEFAULT");
                if (posDef > 0)
                {
                    string val = _exp.Substring(posDef + 7).TrimStart();
                    if (!_NullAble)
                        _Default = val.Substring(0, val.IndexOf(" "));
                    else
                        _Default = val.Trim();
                }
                string field = null;
                string property = null;
                field = _exp.Substring(0, _exp.IndexOf(" "));
                string temp = _exp.Substring(field.Length);
                if (posDef > 0 || posNull > 0)
                    property = temp.Trim().Substring(0, temp.Trim().IndexOf(" "));
                else
                    property = temp.Trim();
                FieldName = field;
                Utils.GetProperty(property, ref _type, ref _precision, ref _Scale);
            }
        }

        /// <summary>
        /// 序号
        /// </summary>
        public int IndexID { get; set; }
        /// <summary>
        /// 字段名称
        /// </summary>
        public string FieldName { get; set; }
        private FieldType _type = FieldType.Varchar2;
        /// <summary>
        /// 字段类型
        /// </summary>
        public FieldType Type
        {
            get { return _type; }
            set { _type = value; }
        }
        private int _precision = 0;
        /// <summary>
        /// 数字可用的最大位数（如果有小数点的话，是小数点前后位数之和）
        /// </summary>
        public int Precision
        {
            get { return _precision; }
            set { _precision = value; }
        }
        private int _Scale = -1;
        /// <summary>
        /// 小数点右侧的最大位数
        /// </summary>
        public int Scale
        {
            get
            {
                return _Scale;
            }
            set
            {
                _Scale = value;
            }
        }
        private bool _NullAble = true;
        /// <summary>
        /// 可为空
        /// </summary>
        public bool NullAble
        {
            get
            {
                return _NullAble;
            }
            set
            {
                _NullAble = value;
            }
        }
        public object _Default = null;
        /// <summary>
        /// 默认值
        /// </summary>
        public object Default
        {
            get
            {
                return _Default;
            }
            set
            {
                if (value != null && value != DBNull.Value)
                    _Default = value.ToString();
                else
                    _Default = null;
            }
        }
        /// <summary>
        /// 注释
        /// </summary>
        public string Tag { get; set; }
        /// <summary>
        /// 字段属性,表达式
        /// </summary>
        public string Expression
        {
            get
            {
                string isNotNull = NullAble ? null : " not null";
                string length = Precision > 0 ? (Scale > 0 ? (Type == FieldType.Timestamp ? string.Format("({0})", Scale) : string.Format("({0},{1})", Precision, Scale)) : string.Format("({0})", Precision)) : null;
                string defaultVal = this.GetDefault;
                string field = string.Format("{0} {1}", FieldName, Type);
                return string.Format("{0}{1}{2}{3}", field, length, defaultVal, isNotNull);// DEC NUMBER(10,2) DEFAULT 0 not null
            }
        }

        public string Property
        {
            get
            {
                string isNotNull = NullAble ? null : " not null";
                string length = Precision > 0 ? (Scale > 0 ? (Type == FieldType.Timestamp ? string.Format("({0})", Scale) : string.Format("({0},{1})", Precision, Scale)) : string.Format("({0})", Precision)) : null;
                string defaultVal = this.GetDefault;
                return string.Format("{0}{1}{2}", Type, length, defaultVal, isNotNull);
            }
        }

        public override string ToString()
        {
            return Expression.ToString();
        }

        private string GetDefault
        {
            get
            {
                if (Default != null && !string.IsNullOrEmpty(Default.ToString()))
                {
                    string _default = null;
                    switch (Type)
                    {
                        case FieldType.Dec:
                        case FieldType.Decimal:
                        case FieldType.Float:
                        case FieldType.Int:
                        case FieldType.Integer:
                        case FieldType.Long:
                        case FieldType.Number:
                        case FieldType.Numeric:
                        case FieldType.Smallint:
                            _default = string.Format(" default {0}", Default);
                            break;
                        default:
                            _default = string.Format(" default '{0}'", Default);
                            break;
                    }
                    return _default;
                }
                return null;
            }
        }
    }
}
